package com.weilele.mvvm.view

import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.util.AttributeSet
import com.weilele.mvvm.R
import com.weilele.mvvm.utils.printStackTrace
import com.weilele.mvvm.widget.BaseSurfaceView
import kotlinx.coroutines.CoroutineScope
import kotlin.math.abs
import kotlin.math.sin


open class JumpPointView : BaseSurfaceView {


    //跳动指针的集合
    private var pointers: MutableList<Float> = mutableListOf()

    //跳动指针的数量
    var pointerNum = 4

    //逻辑坐标 原点
    private var basePointX = 0f
    private var basePointY = 0f

    //指针间的间隙  默认5dp
    private var pointerPadding = 0f

    //每个指针的宽度 默认3dp
    var pointerWidth = 20f

    //指针的颜色
    private var pointerColor = Color.RED

    //指针波动速率,数值越小速度越慢
    var pointerSpeed = 0.03f

    var pointerBgColor = Color.TRANSPARENT

    constructor(context: Context) : this(context, null)
    constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    ) {
        //取出自定义属性
        if (attrs != null) {
            val ta = context.obtainStyledAttributes(attrs, R.styleable.JumpPointView)
            pointerColor = ta.getColor(R.styleable.JumpPointView_pointerColor, pointerColor)
            pointerNum =
                ta.getInteger(R.styleable.JumpPointView_pointerNum, pointerNum) //指针的数量，默认为4
            pointerWidth =
                ta.getDimension(R.styleable.JumpPointView_pointerWidth, pointerWidth) //指针的宽度，默认5dp
            pointerSpeed = ta.getFloat(R.styleable.JumpPointView_pointerSpeed, pointerSpeed)
            pointerBgColor = ta.getColor(R.styleable.JumpPointView_bgColor, pointerBgColor)
            ta.recycle()
        }
    }

    //画笔
    private val paint: Paint by lazy {
        Paint().apply {
//            strokeCap = Paint.Cap.ROUND
            isAntiAlias = true
            color = pointerColor
        }
    }


    fun setPointerColor(pointerColor: Int) {
        this.pointerColor = pointerColor
        paint.color = pointerColor
    }

    /**
     * 在onLayout中做一些，宽高方面的初始化
     */
    private val random = java.util.Random()
    private var isOnLayout = true
    override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
        isOnLayout = true
        super.onLayout(changed, left, top, right, bottom)
        //获取逻辑原点的，也就是画布左下角的坐标。这里减去了paddingBottom的距离
        basePointY = height - paddingBottom.toFloat()
        pointers.clear()
        for (i in 0 until pointerNum) {
            //创建指针对象，利用0~1的随机数 乘以 可绘制区域的高度。作为每个指针的初始高度。
            pointers.add((0.1 * (random.nextInt(10) + 1) * (height - paddingBottom - paddingTop)).toFloat())
        }
        //计算每个指针之间的间隔  总宽度 - 左右两边的padding - 所有指针占去的宽度  然后再除以间隔的数量
        pointerPadding =
            (width - paddingLeft - paddingRight - pointerWidth * pointerNum) / (pointerNum - 1)
        isOnLayout = false
    }

    private var i = 0f

    @Synchronized
    override suspend fun CoroutineScope.drawOnThread(canvas: Canvas) {
        //创建一个死循环，每循环一次i+0.1
        try {
            if (!isOnLayout) {
                for (j in pointers.indices) { //循环改变每个指针高度
                    val rate = abs(sin(i + j.toDouble())).toFloat() //利用正弦有规律的获取0~1的数。
                    pointers[j] = (basePointY - paddingTop) * rate //rate 乘以 可绘制高度，来改变每个指针的高度
                }
                i += pointerSpeed
                startDrawPoint(canvas)
            }
        } catch (e: InterruptedException) {
            printStackTrace { e }
        }
    }

    @Synchronized
    private fun startDrawPoint(canvas: Canvas) {
        if (isOnLayout) {
            return
        }
        clearCanvas(canvas)
        canvas.drawColor(pointerBgColor)
        //将x坐标移动到逻辑原点，也就是左下角
        basePointX = 0f + paddingLeft
        //循环绘制每一个指针。
        for (i in pointers.indices) {
            if (i < pointers.count()) {
                //绘制指针，也就是绘制矩形
                canvas.drawRect(
                    basePointX,
                    basePointY - pointers[i],
                    basePointX + pointerWidth,
                    basePointY,
                    paint
                )
                basePointX += pointerPadding + pointerWidth
            }
        }
    }

    override fun isDrawOnThreadLoop(): Boolean {
        return true
    }
}